/**
 * 组件系统核心
 *
 * 定义React风格组件类和组件管理器，处理组件的生命周期和状态管理
 */

import { ReactElement } from "./createElement";

/**
 * 组件属性接口
 * 定义组件可接收的输入参数
 */
export interface ComponentProps {
  /** 子元素内容 */
  children?: any;
  /** 其他任意属性 */
  [key: string]: any;
}

/**
 * 组件状态接口
 * 定义组件内部可维护的状态
 */
export interface ComponentState {
  /** 任意状态属性 */
  [key: string]: any;
}

/**
 * 组件基类
 *
 * 提供类似React的组件功能，包括属性、状态管理和生命周期
 *
 * @template P 组件属性类型
 * @template S 组件状态类型
 */
export class Component<
  P extends ComponentProps = {},
  S extends ComponentState = {}
> {
  /** 组件属性 */
  props: P;

  /** 组件内部状态 */
  state: S;

  /** 更新处理函数，由渲染器注入 */
  updater: null | (() => void) = null;

  /**
   * 创建组件实例
   * @param props 初始属性
   */
  constructor(props: P) {
    this.props = props;
    this.state = {} as S;
  }

  /**
   * 更新组件状态并触发重新渲染
   *
   * @param partialState 部分状态或状态计算函数
   */
  setState(
    partialState: Partial<S> | ((prevState: S, props: P) => Partial<S>)
  ): void {
    // 计算新状态
    const newState =
      typeof partialState === "function"
        ? (partialState as Function)(this.state, this.props)
        : partialState;

    // 合并状态
    this.state = { ...this.state, ...newState };

    // 触发更新
    if (this.updater) this.updater();
  }

  /**
   * 强制更新组件，不改变状态
   */
  forceUpdate(): void {
    if (this.updater) this.updater();
  }

  /**
   * 生命周期：组件更新后调用
   *
   * @param prevProps 更新前的属性
   * @param prevState 更新前的状态
   */
  componentDidUpdate?(prevProps: P, prevState: S): void;

  /**
   * 生命周期：组件挂载后调用
   */
  componentDidMount?(): void;

  /**
   * 生命周期：组件卸载前调用
   */
  componentWillUnmount?(): void;

  /**
   * 渲染组件，返回虚拟DOM结构
   * 子类必须实现此方法
   */
  render(): ReactElement | null {
    return null;
  }
}

/**
 * 组件状态接口
 * 用于管理UI组件的可见性和生命周期状态
 */
export interface ComponentStatus {
  /** 组件是否可见 */
  visible: boolean;
  /** 组件是否已挂载 */
  mounted: boolean;
  /** 组件最后更新时间戳 */
  lastUpdated: number;
  /** 自定义状态数据 */
  customState?: Record<string, any>;
}

/**
 * UI组件管理器
 * 负责注册、查找和控制UI组件的中央管理系统
 */
class UIComponentManager {
  /** 组件存储表 */
  private components: Record<string, UiRenderable> = {};

  /**
   * 注册UI组件
   * @param name 组件唯一标识
   * @param node UI节点对象
   * @returns 注册的节点对象
   */
  private register(name: string, node: UiRenderable): UiNode {
    this.components[name] = node;
    return this.components[name];
  }

  /**
   * 获取已注册的组件
   *
   * @template T 组件类型
   * @param name 组件标识
   * @returns 组件实例或undefined
   */
  get<T extends UiRenderable>(name: string): T | undefined {
    return this.components[name] as T | undefined;
  }

  /**
   * 显示组件
   * @param name 组件标识
   */
  show(name: string): void {
    const node = this.components[name];
    if (node) {
      node.visible = true;
    }
  }

  /**
   * 隐藏组件
   * @param name 组件标识
   */
  hide(name: string): void {
    const node = this.components[name];
    if (node) {
      node.visible = false;
    }
  }

  /**
   * 获取所有已注册组件的标识
   * @returns 组件标识数组
   */
  getAllIds(): string[] {
    return Object.keys(this.components);
  }
}

/** 全局UI组件管理器实例 */
const uiComponentMgr = new UIComponentManager();
export { uiComponentMgr };
